package com.sshine.solon.rabbitmq.annotation;

import com.sshine.solon.rabbitmq.core.AcknowledgeMode;

import java.lang.annotation.*;

/**
 * @author sshine
 * @date 2022/7/20
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RabbitListener {

    /**
     * The queues for this listener.
     * The entries can be 'queue name', 'property-placeholder keys' or 'expressions'.
     * Expression must be resolved to the queue name or {@code Queue} object.
     * The queue(s) must exist, or be otherwise defined elsewhere as a bean(s) with
     * a  in the application
     * context.
     * Mutually exclusive with {@link #bindings()} and {@link #queuesToDeclare()}.
     * @return the queue names or expressions (SpEL) to listen to from target
     */
    String[] queues() default {};

    /**
     * The queues for this listener.
     * If there is a  in the
     * application context, the queue will be declared on the broker with default
     * binding (default exchange with the queue name as the routing key).
     * Mutually exclusive with {@link #bindings()} and {@link #queues()}.
     * @return the queue(s) to declare.
     * @since 2.0
     */
    Queue[] queuesToDeclare() default {};

    /**
     * When {@code true}, a single consumer in the container will have exclusive use of the
     * {@link #queues()}, preventing other consumers from receiving messages from the
     * queues. When {@code true}, requires a concurrency of 1. Default {@code false}.
     * @return the {@code exclusive} boolean flag.
     */
    boolean exclusive() default false;

    /**
     * The priority of this endpoint. Requires RabbitMQ 3.2 or higher. Does not change
     * the container priority by default. Larger numbers indicate higher priority, and
     * both positive and negative numbers can be used.
     * @return the priority for the endpoint.
     */
    String priority() default "";

    /**
     * Array of {@link QueueBinding}s providing the listener's queue names, together
     * with the exchange and optional binding information.
     * Mutually exclusive with {@link #queues()} and {@link #queuesToDeclare()}.
     * @return the bindings.
     * @since 1.5
     */
    QueueBinding[] bindings() default {};

    /**
     * If provided, the listener container for this listener will be added to a bean
     * with this value as its name, of type {@code Collection<MessageListenerContainer>}.
     * This allows, for example, iteration over the collection to start/stop a subset
     * of containers.
     * @return the bean name for the group.
     * @since 1.5
     */
    String group() default "";

    /**
     * Set to "true" to cause exceptions thrown by the listener to be sent to the sender
     * using normal {@code replyTo/@SendTo} semantics. When false, the exception is thrown
     * to the listener container and normal retry/DLQ processing is performed.
     * @return true to return exceptions. If the client side uses a
     * {@code RemoteInvocationAwareMessageConverterAdapter} the exception will be re-thrown.
     * Otherwise, the sender will receive a {@code RemoteInvocationResult} wrapping the
     * exception.
     * @since 2.0
     */
    String returnExceptions() default "";

    /**
     * Set an
     * {@link org.springframework.amqp.rabbit.listener.api.RabbitListenerErrorHandler} to
     * invoke if the listener method throws an exception. A simple String representing the
     * bean name. If a Spel expression (#{...}) is provided, the expression must
     * evaluate to a bean name or a
     * {@link org.springframework.amqp.rabbit.listener.api.RabbitListenerErrorHandler}
     * instance.
     * @return the error handler.
     * @since 2.0
     */
    String errorHandler() default "";

    /**
     * Set to true or false, to override the default setting in the container factory.
     * @return true to auto start, false to not auto start.
     * @since 2.0
     */
    String autoStartup() default "";

    /**
     * Set the task executor bean name to use for this listener's container; overrides
     * any executor set on the container factory.
     * @return the executor bean name.
     * @since 2.2
     */
    String executor() default "";

    /**
     * Override the container factory
     * {@link AcknowledgeMode} property. Must be one of the
     * valid enumerations. If a SpEL expression is provided, it must evaluate to a
     * {@link String} or {@link AcknowledgeMode}.
     * @return the acknowledgement mode.
     * @since 2.2
     */
    String ackMode() default "";

}
